<script setup lang="ts" name="CheckUpReport">
import {HeaderData} from '@/components/dTable/dTable'
import dTable from '@/components/dTable/dTable.vue'
import {ElMessage, FormRules, UploadProps, UploadRawFile} from 'element-plus'
import {computed, onMounted, reactive, ref} from 'vue'
import useUser from '@/store/user'
import {
  CheckReportFileList,
  CheckReportItemGroup,
  getCheckInfo,
  getItemGroup,
  getItemGroupRequired,
  rejectCheckReport,
  saveCheckReport
} from '@/api/medicalExaminerDesk/beginPhysicalExamination/inspectionReport'
import {NotLeadingAndTrailingSpaces} from '@/util/common'
import {showMessageBox} from '@/util/element'
const user = useUser.setup().store

const props = defineProps({
  // 体检登记表id
  checkupRegisterId: {
    type: String,
    required: true,
    default: ''
  },
  // 禁止编辑
  disEdit: {
    type: Boolean,
    required: true,
    default: false
  },
  // 性别
  gender: {
    type: String,
    required: false,
    default: ''
  }
})

// 保存和拒检的加载
const showSaveLoading = ref<boolean>(false)

//体检医生id
const dutyDoctorId = ref<string | undefined>()
// 体检医生姓名
const dutyDoctorName = ref<string | undefined>()

// 体检大类的体检医生姓名
const dutyDoctorName10 = computed(() => {
  return dutyDoctorName.value || (user.userInfor?.jobName === '医生' ? user.userInfor?.userName : '')
})

//默认选中
const defualtSeleted = ref<CheckReportItemGroup | undefined>(undefined)

// 项目组合是否必填
const fieldRequired = ref<boolean>(false)

// 体检状态
const checkupStatus = ref<number | undefined>()

// 体检状态
const checkupStatus10 = computed(() => {
  return checkupStatus.value
})

// 左侧列表
const tableRef = ref()

// 表单实例
const formRef = ref()

// 空数据
const emptyData: Partial<CheckReportItemGroup> = {
  description: '', // 描述
  result: '', // 结论
  isNormal: 1, // 是否异常
  fileList: [], // 预览文件
  imageList: [] // 文件信息
}

// 表单数据
let formData = reactive<Partial<CheckReportItemGroup>>({
  ...emptyData
})

const rules = computed<FormRules>(() => {
  return {
    description: [
      {required: fieldRequired.value, message: '请输入检查描述!', trigger: ['blur']},
      {
        message: '最多500个字符!',
        trigger: ['change', 'blur'],
        max: 500
      },
      {
        message: '首尾不能为空格!',
        pattern: NotLeadingAndTrailingSpaces,
        trigger: ['change', 'blur']
      }
    ],
    result: [
      {required: fieldRequired.value, message: '请输入检查结论!', trigger: ['blur']},
      {
        message: '最多500个字符!',
        trigger: ['change', 'blur'],
        max: 500
      },
      {
        message: '首尾不能为空格!',
        pattern: NotLeadingAndTrailingSpaces,
        trigger: ['change', 'blur']
      }
    ]
    // fileList: [{required: fieldRequired.value, type: 'array', message: '请上传影像附件!', trigger: ['change', 'blur']}]
  }
})

// 检查报告类型表头
const checkUpReportTypeHeader = ref<Array<HeaderData>>([{prop: 'itemGroupName', label: '检查项目组合', columnType: 'text', align: 'left', 'min-width': '200'}])
// 检查报告类型列表
const checkUpReportType = ref<Array<CheckReportItemGroup>>([])

// 预览图片地址
const dialogImageUrl = ref<string>('')
// 预览图片弹窗
const dialogVisible = ref<boolean>(false)

/**
 * @description: 文件上传前钩子
 * @param {*} file
 * @return {*}
 */
const beforeUpload = (file: UploadRawFile) => {
  const type = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
  if (type.indexOf(file.type) === -1) {
    ElMessage.error('上传文件类型为.jpg, .jpeg, .gif, .png')
    return false
  } else if (file.size / 1024 / 1024 > 4) {
    ElMessage.error('上传文件大小不超过4MB!')
    return false
  }
  return true
}

/**
 * @description: 移除文件
 * @return {*}
 */
const handleRemove: UploadProps['onRemove'] = (uploadFile) => {
  formData.imageList = formData.imageList?.filter((imgItem) => {
    return imgItem.fileName !== uploadFile.name
  })
}

/**
 * @description: 上传文件状态改变
 * @return {*}
 */
const handleUploadSuccess: UploadProps['onSuccess'] = (response) => {
  // 给后端的数据
  formData.imageList?.push({
    checkupRegisterId: props.checkupRegisterId,
    itemGroupId: defualtSeleted.value?.itemGroupId,
    fileUrl: response?.data?.fileUrl,
    fileName: response?.data?.fileName,
    name: response?.data?.fileName,
    fileSize: response?.data?.fileSize,
    base64: response?.data?.base64
  })
  // 文件回显
  formData.fileList =
    formData.imageList?.map((el) => {
      return {name: el.fileName, url: el.base64} as CheckReportFileList
    }) || []
}

/**
 * @description: 预览文件
 * @return {*}
 */
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url || ''
  dialogVisible.value = true
}

// 如果没有检验项目禁用编辑
const disEdit10 = computed(() => {
  return checkUpReportType.value.length === 0
})

/**
 * @description: 获取体检信息
 * @return {*}
 */
const getInitData = () => {
  props.checkupRegisterId &&
    getItemGroup({checkupRegisterId: props.checkupRegisterId, checkType: 3})
      .then((res) => {
        const {data} = res.data
        // 左侧项目组合数据
        checkUpReportType.value = data
        // 默认选择第一行显示右侧数据
        if (!checkUpReportType.value?.length) {
          defualtSeleted.value = undefined
          formData = {...emptyData}
        } else {
          // 默认第一行
          !defualtSeleted.value && (defualtSeleted.value = checkUpReportType.value[0])
        }
        // 找到选中行的坐标
        const rowIndex = checkUpReportType.value?.findIndex((item) => {
          return item.itemGroupId === defualtSeleted.value?.itemGroupId
        })
        tableRef.value?.setSeleted(checkUpReportType.value[rowIndex]) // 选中上次的行
      })
      .catch((err) => {
        console.warn(err)
      })
      .finally(() => {
        showSaveLoading.value = false
      })
}

/**
 * @description: 保存
 * @return {*}
 */
const onSave10 = () => {
  formRef.value &&
    formRef.value.validate((valid: boolean, fields) => {
      if (valid) {
        showSaveLoading.value = true
        const baseParams = {
          checkupStatus: 2, //2已检
          checkupRegisterId: props.checkupRegisterId,
          dutyDoctorId: dutyDoctorId.value || user.userInfor?.id,
          dutyDoctorName: dutyDoctorId.value !== user.userInfor?.id ? dutyDoctorName.value || user.userInfor?.userName : user.userInfor?.userName,
          checkType: 3 // 检查类型
        }
        const params: Array<Partial<CheckReportItemGroup>> = []
        // 去掉base64字段
        const fileList = formData.imageList?.map((item) => {
          delete item.base64
          return item
        })
        params.push({
          ...baseParams,
          itemGroupId: defualtSeleted.value?.itemGroupId, // 项目组合id
          itemGroupCode: defualtSeleted.value?.itemGroupCode, // 项目组合编码
          itemGroupName: defualtSeleted.value?.itemGroupName, // 项目组合名称
          itemName: formData?.itemName, // 项目名称
          itemCode: formData?.itemCode, // 项目编码
          itemId: formData?.itemId, // 项目id
          description: formData.description, // 检查描述
          isNormal: formData.isNormal, // 是否正常
          result: formData.result, // 结果
          id: formData.id,
          imageList: fileList
        })
        saveCheckReport(params)
          .then(() => {
            getInitData()
            ElMessage.success(`${defualtSeleted.value?.itemGroupName}保存成功!`)
          })
          .catch((err) => {
            showSaveLoading.value = false
            console.warn(err)
          })
      } else {
        console.warn(fields)
      }
    })
}

/**
 * @description: 拒检
 * @return {*}
 */
const onRejectInspection10 = () => {
  showMessageBox('是否对该体检大类进行拒检操作？', {title: '拒检确认', mesageType: 'base'})
    .then(() => {
      showSaveLoading.value = true
      const baseParams = {
        checkupRegisterId: props.checkupRegisterId, // 体检登记表id
        dutyDoctorId: dutyDoctorId.value || user.userInfor?.id, // 体检医生id
        dutyDoctorName: dutyDoctorId.value !== user.userInfor?.id ? dutyDoctorName.value || user.userInfor?.userName : user.userInfor?.userName, // 体检医生姓名
        checkupStatus: 1, // 1拒检
        checkType: 3 // 检查类型
      }
      const params: Array<Partial<CheckReportItemGroup>> = []
      params.push({
        ...baseParams,
        itemGroupId: defualtSeleted.value?.itemGroupId, // 项目组合id
        itemGroupCode: defualtSeleted.value?.itemGroupCode, // 项目组合编码
        itemGroupName: defualtSeleted.value?.itemGroupName, // 项目组合名称
        itemName: formData?.itemName, // 项目名称
        itemCode: formData?.itemCode, // 项目编码
        itemId: formData?.itemId, // 项目id
        description: null, // 检查描述
        isNormal: 1, // 是否正常
        result: null, // 结果
        id: formData.id
      })
      rejectCheckReport(params)
        .then(() => {
          ElMessage.success(`${defualtSeleted.value?.itemGroupName}拒检成功!`)
          getInitData()
        })
        .catch((error) => {
          showSaveLoading.value = false
          console.warn(error)
        })
    })
    .catch((error) => {
      console.warn(error)
    })
}

/**
 * @description: 获取项目组合的必填项
 * @param {*} itemGroupId
 * @return {*}
 */
const getRequiredFilds = (itemGroupId: string) => {
  getItemGroupRequired({itemGroupIds: itemGroupId}).then((res) => {
    fieldRequired.value = !!res.data?.data?.[0].isRequired
  })
}

//行点击回调
const onRowClick = (row: CheckReportItemGroup) => {
  if (row) {
    getRequiredFilds(row.itemGroupId)
    defualtSeleted.value = row // 左侧列表当前选中行
    const params = {
      checkupRegisterId: props.checkupRegisterId, // 体检登记表id
      checkType: 3, // 检查类型
      itemGroupId: row.itemGroupId //  项目组合id
    }
    getCheckInfo(params)
      .then((res) => {
        const {data} = res.data
        formData.id = data?.id // id
        formData.description = data?.description // 描述
        formData.result = data?.result // 结论
        formData.isNormal = data?.isNormal || 1 // 默认正常
        // 用于回显
        formData.fileList =
          data?.imageList?.map((el) => {
            return {name: el.fileName, url: el.base64} as CheckReportFileList
          }) || []
        // 真实影像数据
        formData.imageList = data?.imageList || []
        formData.itemCode = data?.itemCode
        formData.itemId = data?.itemId
        formData.itemName = data?.itemName
        dutyDoctorId.value = data?.dutyDoctorId
        dutyDoctorName.value = data?.dutyDoctorName
        checkupStatus.value = data?.checkupStatus
      })
      .finally(() => {
        formRef.value?.clearValidate()
      })
  } else {
    defualtSeleted.value = undefined
    formData = {...emptyData}
    checkupStatus.value = undefined
  }
}

onMounted(() => {
  getInitData()
})
</script>
<template>
  <div class="d-common-flex-full d-common-full d-check-up-desk-content">
    <d-table ref="tableRef" class="checkUp-report-type" :table-data="checkUpReportType" :table-header-data="checkUpReportTypeHeader" :default-seleted="defualtSeleted" @row-click="onRowClick" />
    <el-form ref="formRef" class="checkUp-report" :rules="rules" :model="formData" :disabled="disEdit10 || disEdit">
      <el-form-item prop="description" class="inspection-description">
        <div class="title d-common-flex-algin-center">
          检查描述
        </div>
        <el-input v-model="formData.description" type="textarea" clearable />
      </el-form-item>
      <el-form-item prop="result" class="inspection-conclusion">
        <div class="title d-common-flex-algin-center">
          <span>检查结论</span>
          <el-radio-group v-model="formData.isNormal">
            <el-radio :label="1">
              正常
            </el-radio>
            <el-radio :label="2">
              异常
            </el-radio>
          </el-radio-group>
        </div>
        <el-input v-model="formData.result" type="textarea" clearable />
      </el-form-item>
      <el-form-item prop="fileList" class="image-attachment">
        <div class="title d-common-flex-algin-center">
          <span>影像附件</span>
        </div>
        <div class="image-attachment-box">
          <el-upload
            v-model:file-list="formData.fileList"
            action="/api/checkReportImage/upload"
            :headers="{Authorization: useUser.setup().store.token}"
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemove"
            :before-upload="beforeUpload"
            :on-success="handleUploadSuccess"
            :disabled="disEdit10 || disEdit"
            accept=".jpg, .jpeg, .gif, .png"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>
          <el-dialog v-model="dialogVisible" :width="700">
            <img w-full :src="dialogImageUrl" alt="Preview Image" class="preview-image">
          </el-dialog>
        </div>
      </el-form-item>
    </el-form>
  </div>
  <div class="d-check-up-desk-footer d-common-flex-center d-common-width-full">
    <span class="doctor">体检医生：</span>
    <el-input v-model="dutyDoctorName10" disabled />
    <el-button type="primary" :loading="showSaveLoading" :disabled="disEdit10 || disEdit" @click="onSave10()">
      保存
    </el-button>
    <el-button type="danger" :loading="showSaveLoading" :disabled="disEdit10 || (checkupStatus10 && checkupStatus10 === 1) || disEdit" plain @click="onRejectInspection10()">
      拒检
    </el-button>
  </div>
</template>
<style scoped lang="less">
.checkUp-report-type {
  width: 260px;
  height: 72vh;
  :deep(.current-row) {
    .el-table__cell {
      background: transparent;
      .cell {
        background: var(--el-table-current-row-bg-color);
      }
    }
  }
  :deep(.el-table__cell) {
    border: none;
    .cell {
      width: 244px !important;
      height: 32px;
      margin: 0 auto;
      line-height: 32px;
      border-radius: 4px;
      cursor: pointer;
    }
  }
}
.checkUp-report {
  flex: 1;
  margin-left: 12px;
  :deep(.el-form-item__content) {
    display: block;
  }
  .title {
    height: 32px;
    background: #f2f2f2;
    font-weight: bold;
    padding-left: 19px;
    border: 1px solid #dddddd;
    border-bottom: none;
    span {
      margin-right: 21px;
    }
  }
  .inspection-description,
  .inspection-conclusion {
    margin-bottom: 14px;
    :deep(.el-textarea__inner) {
      border-radius: 0;
      height: 200px;
    }
  }
  .image-attachment {
    .title {
      height: 40px;
    }
    .image-attachment-box {
      border: 1px solid #dddddd;
      border-top: none;
      height: 320px;
      padding: 12px;
      overflow: auto;
    }
    &.is-error {
      .image-attachment-box {
        box-shadow: 0 0 0 1px var(--el-color-danger) inset;
      }
    }
    :deep(.el-upload-list__item) {
      width: 162px;
      height: 156px;
    }
    :deep(.el-upload) {
      width: 162px;
      height: 156px;
    }
  }
  .preview-image {
    width: 100%;
    height: 100%;
  }
}
:deep(.el-upload-list__item-status-label) {
  background: var(--theme-color);
}
</style>
